﻿using System;

namespace VitCode.ObjectResolutionHelper
{
    /// <summary>
    /// Excel文档生成需用要到的Excel操作类
    /// </summary>
    public class ExcelOperateHelper
    {
        /// <summary>
        /// 通过参照单元格名称加上横向偏移值与纵向偏移值,得到目标单元格名称
        /// </summary>
        /// <param name="startCellName">参照物(Excel单元格名称)</param>
        /// <param name="rowAddNum">向下偏移多少行</param>
        /// <param name="columnAddNum">向右偏移多少列</param>
        /// <returns>目标单元格名称</returns>
        public static string GetEndCellName(string startCellName, int rowAddNum, int columnAddNum)
        {
            int[] startCellCoordinate = GetCoordinate(startCellName);
            int endCellRowNum = startCellCoordinate[0] + rowAddNum;
            int endCellColumnNum = startCellCoordinate[1] + columnAddNum;
            string cellColumnName = "";
            for (int i = 0; i < endCellColumnNum.ToString().Length; i++)//这个算法有效能不高,应该找阿勇进行优化
                cellColumnName = GetColumnCharString(endCellColumnNum, i + 1) + cellColumnName;
            return cellColumnName + endCellRowNum.ToString();
        }

        /// <summary>
        /// 把单元格名称转换成行号与列号
        /// </summary>
        /// <param name="cellName">单元格名称</param>
        /// <returns>string[]{行号,列号}</returns>
        public static int[] GetCoordinate(string cellName)
        {
            int columnIndex = 0;
            int rowIndex = 0;
            char[] chars = cellName.ToCharArray();
            int charCount = 0, numCount = 0;
            for (int i = chars.Length - 1; i >= 0; i--)
            {
                if (chars[i] >= '0' && chars[i] <= '9')
                {
                    rowIndex += Convert.ToInt32(Math.Pow(10, numCount))*(Convert.ToInt32(chars[i]) - 48);
                    numCount++;
                }
                else if (chars[i] >= 'A' && chars[i] <= 'Z')
                {
                    columnIndex += Convert.ToInt32(Math.Pow(26, charCount))*(Convert.ToInt32(chars[i]) - 64);
                    charCount++;
                }
                else
                    throw new ArgumentOutOfRangeException("單格名稱不符合規格");
            }
            var returnValue = new[] {rowIndex, columnIndex};
            return returnValue;
        }

        /// <summary>
        /// 一个整数向26个字母转换的方法
        /// </summary>
        /// <param name="endCellColumnNum"></param>
        /// <param name="weiShu"></param>
        /// <returns></returns>
        public static string GetColumnCharString(int endCellColumnNum, int weiShu)
        {
            if (endCellColumnNum == 1 || endCellColumnNum > Math.Pow(26, weiShu - 1))
                return
                    Convert.ToChar(
                        Convert.ToInt32(Math.Floor(Convert.ToDouble(endCellColumnNum)/Math.Pow(26, weiShu - 1)))%26 + 64)
                        .
                        ToString();
            else
                return "";
        }
    }
}